package xyz.xtgl.config.helper;

import common.core.dto.LoginUserDto;
import common.core.util.CommonUtil;
import common.core.util.LoginUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import xyz.xtgl.oahth2.config.constant.GlobalConstant;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@Slf4j
public class TokenAutnenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(request);
        String header = requestWrapper.getHeader(GlobalConstant.AUTHORIZATION_HEADER_KEY);
        String token = StringUtils.substringAfter(header, GlobalConstant.AUTHORIZATION_HEADER_BEFORE_STRING);
        if(CommonUtil.isEmpty(token)){
            Cookie[] cookies = requestWrapper.getCookies();
            if(CommonUtil.isNotEmpty(cookies)){
                for (Cookie cookie : cookies) {
                    if(cookie.getName().equals(GlobalConstant.AUTHORIZATION_COOKIE_TOKENKEY)){
                        requestWrapper.addHeader(GlobalConstant.AUTHORIZATION_HEADER_KEY ,
                                GlobalConstant.AUTHORIZATION_HEADER_BEFORE_STRING + cookie.getValue());
                    }
                }
            }
        }
        //解析出头中的token
        if(CommonUtil.isNotEmpty(token)){
            Jwt jwt = JwtHelper.decode(token);
            Map<String, Object> map = CommonUtil.convertJsonToObject(jwt.getClaims(),Map.class);
            LoginUserDto dto = CommonUtil.convertJsonToObject((String)map.get("user_name"), LoginUserDto.class);
            LoginUtil.init(dto);
            //将用户信息和权限填充 到用户身份token对象中
            UsernamePasswordAuthenticationToken authenticationToken
                    = new UsernamePasswordAuthenticationToken(dto,null, AuthorityUtils.createAuthorityList(new String[]{}));
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(requestWrapper));
            //将authenticationToken填充到安全上下文
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }

        filterChain.doFilter(requestWrapper,response);
    }

}
